# -*- coding: utf-8 -*-
#===============================================================================
# Koro Business Environment
# Copyright (C) 2008  Antonio Corroppoli
#
#This file is part of Koro BE.
# 
# Koro BE is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# Koro BE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Koro BE; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#===============================================================================

'''
Created on 20/ago/2011

@author: antstud
'''

import wx
from koro import util
from koro.modules import lookup
from koro.modules.documenti.ui import panel
from koro.modules.documenti.canvas import DocumentoCanvas, PreventivoCanvas
from koro.ui.wxgui.widgets import controls as co,dialogs
from koro.ui.wxgui.pages import ListPage
from koro.ui.wxgui.panels import Table

ID_ARRIVO_MERCE=wx.NewId()

#class DocumentiObjectDialog(dialogs.KoroObjectDialog):
#    def __init__(self,*args,**kwargs):
#        dialogs.KoroObjectDialog.__init__(self,*args,**kwargs)


def get_doc_panel(doc):
        if doc.is_preventivo():
            return panel.PreventivoPanel
        elif doc.is_fattura():
            return panel.FatturaPanel
        elif doc.is_arrivo():
            return panel.ArrivoMercePanel
        elif doc.is_reg_fatt_forn():
            return panel.RegFattFornPanel
        else:
            raise Exception('Documento non riconosciuto: {0}'.format(doc.tipo_documento))


#===============================================================================
# DocumentiListPage
#===============================================================================
class DocumentiListPage(ListPage):
    TITLE='Documenti'
    def __init__(self,*args,**kwargs):
        ListPage.__init__(self,*args,**kwargs)
        self.list_manager.bind_callback(wx.EVT_LIST_ITEM_ACTIVATED,
                                        self._mostra_documento_callback)
        self._configure_list(args[2])
        self._editor_manager=panel.EditorManager(self)
        #self._current_object=None
        #self._object_viewer=None        
    
    def _layout(self):#chiamato dal metodo show.....
        self.Sizer.Add(self.get_toolbar(),(0,0),flag=wx.EXPAND|wx.BOTTOM,border=3)
        self.Sizer.Add(self.list_manager.get_managed_list(),(1,0),flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.TOP|wx.EXPAND|wx.GROW|wx.CENTER,border=5)
        self.Sizer.AddGrowableRow(1)
        self.Sizer.AddGrowableCol(0)
        self.Layout()
    
    def _create_toolbar(self):#viene chiamato dal costruttore di BasePage...
        '''Per configurare la toolbar nelle sottoclassi, ridefinire il metodo
        _configure_toolbar().'''
        self._tb=co.KoroListPageToolBar(self)
        self._configure_delete_tool()                
        self._configure_toolbar()
        self._tb.realize()
#        self.GetSizer().Add(self.get_toolbar(),(0,0),flag=wx.EXPAND|wx.BOTTOM,border=3)        
        #topsizer.Add(wx.StaticLine(self),0,wx.EXPAND|wx.TOP,border=3)
        self._tb.Bind(wx.EVT_TOOL,self._on_action_new,id=wx.ID_NEW)
        self._tb.Bind(wx.EVT_TOOL,self._mostra_documento_handler,id=wx.ID_EDIT)
        self._tb.Bind(wx.EVT_TOOL,self._on_action_delete,id=wx.ID_DELETE)
        self._tb.Bind(wx.EVT_TOOL,self._print_document,id=wx.ID_PRINT)
    
    def _configure_delete_tool(self):
        if not util.is_admin():
            self._tb.RemoveTool(wx.ID_DELETE)
    
    def _print_document(self,evt):
        evt.StopPropagation()
        c=DocumentoCanvas(self.get_selected_object())
        c.print_preview()
    
#    def _viewer_close_handler(self,evt):
#        '''Imposta il codice da processare in base alla richiesta fatta dall'object_viewer. I valori possono essere:
#        * wx.ID_SAVE per salvare l'oggetto,
#        * wx.ID_DELETE per non salvare l'oggetto.'''
#        ret_code=wx.ID_SAVE
#        if self._page_state==self.NEW_STATE:
#            response=wx.GetApp().show_question('Salvare il documento appena creato?')
#            if response==wx.ID_CANCEL:
#                evt.Skip(False)
#                return
#            if response==wx.ID_NO:
#                ret_code=wx.ID_DELETE
#            elif response!=wx.ID_YES:
#                raise#TODO:....che succede qui non deve verificarsi mai
#        try:
#            self._process_code(ret_code)
#            self._object_viewer.end_modal(ret_code)
#        except Exception,inst:#TODO:qui catturo tutto...catturare solo l'eccezione che di save_object
#            print self.__class__.__name__,'_viewer_close_handler: {0}'.format(inst)
#    
#    def _process_code(self,code):
#        '''Processa il codice di una richiesta dell'object_viewer.'''
#        if code==wx.ID_SAVE:
#            self._object_viewer.update_object(self._current_object)
#            self.save_object(self._current_object)
#        elif code==wx.ID_DELETE:
##            self.expunge_object(self._current_object)
#            self.delete_object(self._current_object)
#            del self._current_object
#            self._current_object=None
    
    def _mostra_documento_handler(self,evt):
        '''Handler del click sul tasto 'Visualizza'.'''
        obj=self.get_selected_object()
        if obj is None:
            wx.GetApp().show_message('Selezionare un documento')
            return
        self._mostra_documento_callback(obj,None)
    
    def _mostra_documento_callback(self,obj,index):
        '''Callback dell'evento ITEM_ACTIVATED del list manager.'''
        self.mostra_documento(obj)
#        self._mostra_documento(obj)
#        self.list_manager.refresh_selected()
    
    def _mostra_documento(self,obj):
        object_=self._editor_manager.edit(obj)
        self.set_page_state(self.NORMAL_STATE)
        return object_
        #self._object_viewer.destroy()
    
    def mostra_documento(self,obj):
        self._mostra_documento(obj)
        self.list_manager.refresh_selected()        
    
    def _get_viewer_panel(self):#TODO:ELIMINARE ora c'e' l'editor manager
        '''Restituisce il Panel associato alla ListPage.'''
        pass
    
    def _configure_list(self,objects):
        '''Configura la ListCtrl degli oggetti.'''
        pass
    
    def get_object(self):
        print 'debug:',self.__class__.__name__,'get_object'
        return self._object    
    
    def process_new(self):
        print self.__class__.__name__,'.process_new'
        self.set_page_state(self.NEW_STATE)        
        #richiesta intestatario documento
        dlg=self._get_lookup_intestatario()
        action=dlg.show()
        if action==wx.ID_CANCEL:
            dlg.Destroy()
            return 
        intestatario=dlg.get_selection()
        dlg.Destroy()
        
        self.enable_page(False)
        obj=self._request_new_object()
        obj.set_intestatario(intestatario)
        obj=self._mostra_documento(obj)
        if obj is not None:
            self.list_manager.add_object(obj)
        #self._current_object=None
        self.enable_page()       
            
    
#    def show_object_viewer(self,obj):
#        #self._create_object_viewer()
#        self._object_viewer=dialogs.KoroObjectViewer(self,panel=get_doc_panel(obj)(self))
#        self._object_viewer.bind(wx.EVT_TOOL, self._viewer_close_handler, id=wx.ID_CLOSE)
#        return self._object_viewer.show(obj)
    
#    def __bind(self):
#        self.list_ctrl.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.mostra_documento)
    
    def crea_documento(self,tipo,object):
        '''Crea un documento a partire da quello corrente.'''
        pass


#===============================================================================
# DocumentiListPage
#===============================================================================
#class DocumentiListPage_old(ListPage):
#    TITLE='Documenti'
#    def __init__(self,*args,**kwargs):
#        ListPage.__init__(self,*args,**kwargs)
#        self.list_manager.bind_callback(wx.EVT_LIST_ITEM_ACTIVATED,
#                                        self._mostra_documento_callback)
#        self._configure_list(args[2])
#        self._current_object=None
#        self._object_viewer=None        
#    
#    def _layout(self):#chiamato dal metodo show.....
#        self.Sizer.Add(self.get_toolbar(),(0,0),flag=wx.EXPAND|wx.BOTTOM,border=3)
#        self.Sizer.Add(self.list_manager.get_managed_list(),(1,0),flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.TOP|wx.EXPAND|wx.GROW|wx.CENTER,border=5)
#        self.Sizer.AddGrowableRow(1)
#        self.Sizer.AddGrowableCol(0)
#        self.Layout()
#    
#    def _create_toolbar(self):#viene chiamato dal costruttore di BasePage...
#        '''Per configurare la toolbar nelle sottoclassi, ridefinire il metodo
#        _configure_toolbar().'''
#        self._tb=co.KoroListPageToolBar(self)        
#        self._configure_toolbar()
#        self._tb.realize()
##        self.GetSizer().Add(self.get_toolbar(),(0,0),flag=wx.EXPAND|wx.BOTTOM,border=3)        
#        #topsizer.Add(wx.StaticLine(self),0,wx.EXPAND|wx.TOP,border=3)
#        self._tb.Bind(wx.EVT_TOOL,self._on_action_new,id=wx.ID_NEW)
#        self._tb.Bind(wx.EVT_TOOL,self._mostra_documento_handler,id=wx.ID_EDIT)
#        self._tb.Bind(wx.EVT_TOOL,self._on_action_delete,id=wx.ID_DELETE)
#        self._tb.Bind(wx.EVT_TOOL,self._print_document,id=wx.ID_PRINT)
#    
#    def _print_document(self,evt):
#        evt.StopPropagation()
#    
#    def _viewer_close_handler(self,evt):
#        '''Imposta il codice da processare in base alla richiesta fatta dall'object_viewer. I valori possono essere:
#        * wx.ID_SAVE per salvare l'oggetto,
#        * wx.ID_DELETE per non salvare l'oggetto.'''
#        ret_code=wx.ID_SAVE
#        if self._page_state==self.NEW_STATE:
#            response=wx.GetApp().show_question('Salvare il documento appena creato?')
#            if response==wx.ID_CANCEL:
#                evt.Skip(False)
#                return
#            if response==wx.ID_NO:
#                ret_code=wx.ID_DELETE
#            elif response!=wx.ID_YES:
#                raise#TODO:....che succede qui non deve verificarsi mai
#        try:
#            self._process_code(ret_code)
#            self._object_viewer.end_modal(ret_code)
#        except Exception,inst:#TODO:qui catturo tutto...catturare solo l'eccezione che di save_object
#            print self.__class__.__name__,'_viewer_close_handler: {0}'.format(inst)
#    
#    def _process_code(self,code):
#        '''Processa il codice di una richiesta dell'object_viewer.'''
#        if code==wx.ID_SAVE:
#            self._object_viewer.update_object(self._current_object)
#            self.save_object(self._current_object)
#        elif code==wx.ID_DELETE:
##            self.expunge_object(self._current_object)
#            self.delete_object(self._current_object)
#            del self._current_object
#            self._current_object=None
#    
#    def _mostra_documento_handler(self,evt):
#        '''Handler del click sul tasto 'Visualizza'.'''
#        obj=self.get_selected_object()
#        if obj is None:
#            wx.GetApp().show_message('Selezionare un documento')
#            return
#        self._mostra_documento_callback(obj,None)
#    
#    def _mostra_documento_callback(self,obj,index):
#        '''Callback dell'evento ITEM_ACTIVATED del list manager.'''    
#        self._current_object=obj#self.get_selected_object()
#        self._mostra_documento()
#        self.list_manager.refresh_selected()
#        self._current_object=None
#
##    def _create_object_viewer(self):
##        self._object_viewer=dialogs.KoroObjectViewer(self,panel=self._get_viewer_panel())
##        self._object_viewer.bind(wx.EVT_TOOL, self._viewer_close_handler, id=wx.ID_CLOSE)
#        #self._object_viewer.set_toolbar(self._object_viewer_toolbar(self._object_viewer))
#        #self._object_viewer.get_toolbar().Bind(wx.EVT_TOOL, self._viewer_close_handler, id=wx.ID_CLOSE)
#    
#    def _mostra_documento(self):
#        ret_code=self.show_object_viewer(self._current_object)
#        if ret_code==wx.ID_CANCEL:
#            self._expire_object(self._current_object)
#        self.set_page_state(self.NORMAL_STATE)
#        self._object_viewer.destroy()
#    
#    def _get_viewer_panel(self):
#        '''Restituisce il Panel associato alla ListPage.'''
#        pass
#    
#    def _configure_list(self,objects):
#        '''Configura la ListCtrl degli oggetti.'''
#        pass
#    
#    def get_object(self):
#        print 'debug:',self.__class__.__name__,'get_object'
#        return self._current_object    
#    
#    def process_new(self):
#        print self.__class__.__name__,'.process_new'
#        self.set_page_state(self.NEW_STATE)
#        self.enable_page(False)
#        self._current_object=self._request_new_object()
#        self._mostra_documento()
#        if self._current_object is not None:
#            self.list_manager.add_object(self._current_object)
#        self._current_object=None
#        self.enable_page()    
#    
#    def show_object_viewer(self,obj):
#        #self._create_object_viewer()
#        self._object_viewer=dialogs.KoroObjectViewer(self,panel=get_doc_panel(obj)(self))
#        self._object_viewer.bind(wx.EVT_TOOL, self._viewer_close_handler, id=wx.ID_CLOSE)
#        return self._object_viewer.show(obj)
#    
##    def __bind(self):
##        self.list_ctrl.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.mostra_documento)
#    
#    def crea_documento(self,tipo,object):
#        '''Crea un documento a partire da quello corrente.'''
#        pass
    
#    def _mostra_tabella_documento(self,doc,panel):
#        '''Visualizza i  dati di un documento. Restituisce il documento aggiornato.'''
#        print self.__class__.__name__,'_mostra_tabella_documento'
#        busycursor=wx.BusyCursor()
#        table=Table(self,panel=panel,object=doc)
#        del busycursor
#        action=table.ShowModal()
#        self.add_action(action)
#        obj=table.get_object()
#        table.Destroy()
#        return obj
#    
#    
#    
#    def add_action(self,action):
#        if action==wx.ID_CANCEL:
#            self._action=None
#            return
#        self._action=action
#    
#    def mostra_documento(self,evt):
#        print self.__class__.__name__,'mostra_documento'
#        obj = self._mostra_tabella_documento(panel=self._get_table_panel(), 
#                                     doc=self.get_selected_object())
#        
#        self.save_object(obj)
#        self.process_action()
    
#    def _processa_documento(self,doc):
#        '''Lega un tipo documento con Panel corrispondente. Chiama _mostra_tabella_documento per 
#        visualizzare i dati.'''
#        if doc.is_fattura():
#            doc=self._mostra_tabella_documento(doc,panel.FatturaPanel)
#            if doc is not None:
#                observer=wx.GetApp().get_observer()
#                observer.set_context('FATTURE')
#                observer.save_object(doc)
#                return True
#        if doc.is_arrivo():
#            doc=self._mostra_tabella_documento(doc,panel.ArrivoMercePanel)
#            if doc is not None:
#                observer=wx.GetApp().get_observer()
#                observer.set_context('ARRIVI_MERCE')
#                observer.save_object(doc)
#                return True
#        if doc.is_reg_fatt_forn():
#            doc=self._mostra_tabella_documento(doc,panel.RegFattFornPanel)
#            if doc is not None:
#                observer=wx.GetApp().get_observer()
#                observer.set_context('REG_FATT_FORN')
#                observer.save_object(doc)
#                return True
#        return False


#===============================================================================
# FattureListPage
#===============================================================================
class FattureListPage(DocumentiListPage):
    TITLE='Fatture'
    def __init__(self,*args,**kwargs):
        DocumentiListPage.__init__(self,*args,**kwargs)
    
    def _configure_list(self,objects):
        self.set_list_columns(co.Column('Num.',50,'numero'),
                              co.Column('Tipo',150,'get_tipo_documento_fmt'),
                              co.Column('Data',90,'get_data_documento_fmt'),
                              co.Column('Cliente',200,('intestatario','ragione_sociale')),
                              co.Column('Totale',250,'get_totale_fmt',wx.LIST_FORMAT_RIGHT),
                              )
        
        self.load_list_objects(objects)
    
    def _get_viewer_panel(self):
        '''Restituisce il panel dell'object_viewer.'''
        return panel.FatturaPanel(self)
    
    def _get_lookup_intestatario(self):
        return lookup.LOOKUP_CLIENTI(wx.GetApp().GetTopWindow(),filter=None)


#===============================================================================
# PreventiviListPage
#===============================================================================
class PreventiviListPage(DocumentiListPage):
    TITLE='Preventivi'
    def __init__(self,*args,**kwargs):
        DocumentiListPage.__init__(self,*args,**kwargs)
    
    def _configure_list(self,objects):
        self.set_list_columns(co.Column('Numero',150,'numero'),
                              co.Column('Tipo',150,'get_tipo_documento_fmt'),
                              co.Column('Data',90,'get_data_documento_fmt'),
                              co.Column('Cliente',250,'get_intestatario_fmt'),
                              co.Column('Commento',200,'commento_interno'),
                              co.Column('Totale',250,'get_totale_fmt',wx.LIST_FORMAT_RIGHT),
                                       )
        
        self.load_list_objects(objects)
    
    def _configure_delete_tool(self):
        pass
    
    def _get_viewer_panel(self):
        return panel.PreventivoPanel(self)
    
    def _print_document(self,evt):
        evt.StopPropagation()
        c=PreventivoCanvas(self.get_selected_object())
        c.print_preview()
    
    def _get_lookup_intestatario(self):
        return lookup.LOOKUP_CLIENTI(wx.GetApp().GetTopWindow(),filter=None)

ID_SHOW_FATT_FORN=wx.NewId()
#===============================================================================
# ArriviMerceListPage
#===============================================================================
class ArriviMerceListPage(DocumentiListPage):
    TITLE='Arrivi Merce Fornitore'
    def __init__(self,*args,**kwargs):
        DocumentiListPage.__init__(self,*args,**kwargs)
    
    def _configure_toolbar(self):        
        tb=self.get_toolbar()
        tb.DeleteTool(wx.ID_PRINT)
        tb.AddLabelTool(ID_SHOW_FATT_FORN,
                        "Mostra Reg.Fatt.Forn.",
                        wx.ArtProvider_GetBitmap(wx.ART_NORMAL_FILE,wx.ART_TOOLBAR))
        tb.realize()
        tb.Bind(wx.EVT_TOOL,self._mostra_reg_handler,id=ID_SHOW_FATT_FORN)
    
    def _configure_list(self,objects):
        self.set_list_columns(co.Column('Num.',50,'numero'),
                              co.Column('Data',90,'get_data_documento_fmt'),
                              co.Column('Fornitore',252,('intestatario','ragione_sociale')),
                              co.Column('Documento Generato',250,'get_documento_generato_fmt'),
                              co.Column('Totale',250,'get_totale_fmt',wx.LIST_FORMAT_RIGHT),
                              co.Column('Totale Spese',200,'get_totale_spese_fmt',wx.LIST_FORMAT_RIGHT),
                              )        
        self.load_list_objects(objects)
        
    def _get_viewer_panel(self):
        return panel.ArrivoMercePanel(self)
    
    def _mostra_reg_handler(self,evt):
        doc=self.get_selected_object().get_documento_generato()
        if doc is None:
            return
        self.mostra_documento(doc)
    
    def _get_lookup_intestatario(self):
        return lookup.LOOKUP_FORNITORI(wx.GetApp().GetTopWindow(),filter=None)
    
#    def _registra_fattura(self):#TODO:controllare
#        print self.__class__.__name__,'._registra_fattura'
#        obj=self.get_selected_object()
#        if obj is None:
#            wx.GetApp().show_message('Selezionare un documento.')
#            return
#        if obj.is_chiuso():
#            wx.GetApp().show_message('Fattura Fornitore già registrata.')
#            return
#        busycursor=wx.BusyCursor()
#        try:
#            observer=wx.GetApp().get_observer()
#            observer.set_context('REG_FATT_FORN')            
#            #doc=observer.request_action('REG_FATT_FORN',"genera_reg_fatt_forn",obj)
#            doc=observer.genera_reg_fatt_forn(obj)
#            #save=self._processa_documento(doc)
#            #if save:
#                #observer.set_context('ARRIVI_MERCE')
#                #observer.request_action('ARRIVI_MERCE',"chiudi",obj,doc)
#                #self.update()
#            observer.request_action('ARRIVI_MERCE',"chiudi",obj,doc)            
#        except Exception,err:
#            print err
#            wx.GetApp().show_error("Si e' verificato un errore: {0}".format(err))
#        finally:
#            del busycursor
#    
#    def _on_registra_fattura(self,evt):
##        self._registra_fattura()
#        evt.StopPropagation()


#===============================================================================
# RegFattFornListPage
#===============================================================================
class RegFattFornListPage(DocumentiListPage):
    TITLE='Reg. Fatture Fornitore'
    def __init__(self,*args,**kwargs):
        DocumentiListPage.__init__(self,*args,**kwargs)
#        self.bind_action(ACT_ARRIVO, self._arrivo_merce)        
        #self.get_toolbar().Bind(wx.EVT_TOOL,self._on_arrivo_merce,id=ID_ARRIVO_MERCE)
    
    def _configure_list(self,objects):
        self.set_list_columns(co.Column('Tipo Doc.',150,'get_tipo_documento_fmt'),
                              co.Column('Numero',60,'get_numero_documento_fmt',wx.LIST_FORMAT_RIGHT),
                              co.Column('Data Reg.',80,'get_data_documento_fmt'),
                              co.Column('Fornitore',252,('intestatario','ragione_sociale')),
                              co.Column('Data Fatt.Forn.',100,'get_data_fatt_forn_fmt'),
                              co.Column('Num.Fatt.Forn.',120,'get_numero_fatt_forn_fmt',wx.LIST_FORMAT_RIGHT),
                              co.Column('Totale',100,'get_totale_fmt',wx.LIST_FORMAT_RIGHT),                              
                              )
        self.load_list_objects(objects)
    
    def _configure_toolbar(self):
        self.get_toolbar().DeleteTool(wx.ID_PRINT)
    
    def _get_viewer_panel(self):
        return panel.RegFattFornPanel(self)
    
    def _get_lookup_intestatario(self):
        return lookup.LOOKUP_FORNITORI(wx.GetApp().GetTopWindow(),filter=None)